﻿namespace Taobao.Tools
{
    using Castle.ActiveRecord;
    using Castle.ActiveRecord.Queries;
    using NHibernate.Criterion;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Threading;
    using System.Windows.Forms;
    using Taobao.Model;
    using Top.Api;
    using Top.Api.Domain;
    using Top.Api.Request;
    using Top.Api.Util;
    using System.Configuration;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Xml.Linq; 

    public partial class Form1 : Form
    {
        // Comments
        // 2011-07-27
        // 1: Need adding some time filter on getting the trades. Such as only getting the trades in 6 monthes. 

        #region 

        private static List<string[]> toUpdateTradeStatus = new List<string[]>() {
             new string[]{"WAIT_BUYER_PAY","等待买家付款的订单"},
             new string[]{"TRADE_NO_CREATE_PAY","等待支付宝创建付款的订单"},
             new string[]{"WAIT_SELLER_SEND_GOODS","等待卖家发货的订单"}
        };

        #endregion

        #region Ctor

        private ToolConfiguration Configuration { get; set; }
        private int UpdateBeforeDays = 15;

        public Form1()
        {
            this.InitializeComponent();

            try
            {
                UpdateBeforeDays = Convert.ToInt32(ConfigurationManager.AppSettings["updateBeforeDays"]);
            }
            catch
            {
                UpdateBeforeDays = 15;
            }

            Configuration = ToolConfiguration.Load();
        }

        #endregion

        #region Auto Run

        private void autorun()
        {
            try
            {
                this.toolStripStatusLabel2.Text = "自动处理中";

                if (Configuration.PreparingOperation)
                {
                    this.KeepPreparingOperation();
                    this.toolStripStatusLabel2.Text = "自动处理中，预处理";
                }

                if (Configuration.SentBeforeAllAction)
                {
                    this.KeepSentBeforeAllAction();
                    this.toolStripStatusLabel2.Text = "自动处理中,发货处理";
                }

                if (Configuration.GetRefunds)
                {
                    this.KeepGetRefunds();
                    this.toolStripStatusLabel2.Text = "自动处理中,得到退款信息";
                }
                if (Configuration.GetTrades)
                {
                    this.KeepGetTrades();    //GetTrades
                    this.toolStripStatusLabel2.Text = "自动处理中,得到当前订单";
                }
                if (Configuration.GetTradesInfo)
                {
                    this.KeepGetTradeInfo();  // GetTradesInfo
                    this.toolStripStatusLabel2.Text = "自动处理中,得到订单详细信息";
                }
                if (Configuration.UpdateTradesInfo)
                {
                    this.KeepUpdataTradesInfo();  //UpdataTradesInfo
                    this.toolStripStatusLabel2.Text = "自动处理中,得到同步订单发送信息";
                    UpdataTradesInfo();
                }
                this.toolStripStatusLabel2.Text = "上次处理结束于" + DateTime.Now + ",下一次将在5分钟后启动";

                if (Configuration.Sent)
                {
                    this.KeepSent();
                }

                Thread.Sleep(0x927c0);

                this.autorun();
            }
            catch (Exception exp)
            {
                this.toolStripStatusLabel2.Text = "处理出错，程序会在3秒后重新开始 错误：" + exp.Message;
                Thread.Sleep(0xbb8);
                //this.autorun();
            }
        }

        #endregion

        #region Other Button Click
        private void button1_Click_3(object sender, EventArgs e)
        {
            if (this.button1.Text == "任务暂停")
            {
                this.job.Suspend();
                this.button1.Text = "任务继续";
            }
            else
            {
                this.job.Resume();
                this.button1.Text = "任务暂停";
            }
        }


        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                ActiveRecordStarter.CreateSchema(typeof(Taobao.Model.Refund));
                MessageBox.Show("初始化退款表成功，请在trade 表中添加EndTime字段,类型为datetime");
            }
            catch (Exception)
            {
                MessageBox.Show("初始化退款表失败");
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            this.textBox1.Text = string.Empty;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            SendOutSid();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (this.button6.Text == "关闭日志")
            {
                Console.SetOut(this.systemtw);
                this.button6.Text = "打开日志";
            }
            else
            {
                Console.SetOut(this.customtw);
                this.button6.Text = "关闭日志";
            }
        }

        #endregion
        
        #region Page Load
        private void Form1_Load(object sender, EventArgs e)
        {
            this.customtw = new TextBoxWriter(this.textBox1);
            Console.SetOut(this.customtw);
            this.job = new Thread(new ThreadStart(this.autorun));
            this.job.IsBackground = true;
            this.job.Start();
        }
        #endregion

        #region Helper Methods

        private static TopXmlRestClient CreateClient(Taobao.Model.Shop s)
        {
            return new TopXmlRestClient("http://gw.api.taobao.com/router/rest", s.AppKey, s.AppSecret);
        } 
         
        
        private List<string[]> GetUpdateTradeStatus()
        {
            var result = new List<string[]>();
            if (Configuration.WaitBuyerPay)
                result.Add(new string[] { "WAIT_BUYER_PAY", "等待买家付款的订单" });
            if (Configuration.TradeNoCreatePay)
                result.Add(new string[] { "TRADE_NO_CREATE_PAY", "等待支付宝创建付款的订单" });
            if (Configuration.WaitSellerSendGoods)
                result.Add(new string[] { "WAIT_SELLER_SEND_GOODS", "等待卖家发货的订单" });
            return result;
        }

        private string getSessionKey(string auth_code)
        {
            try
            {
                HttpWebResponse response = (HttpWebResponse)WebRequest.Create("http://container.api.tbsandbox.com/container?authcode=" + auth_code).GetResponse();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return "Error";
                }
                Stream dataStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(dataStream);
                string responseFromServer = reader.ReadToEnd();
                string[] sArray = responseFromServer.Split(new char[] { '&' });
                foreach (string i in sArray)
                {
                    if (i.ToString().StartsWith("top_session"))
                    {
                        return i.ToString().Substring(i.ToString().IndexOf("=") + 1);
                    }
                }
                reader.Close();
                dataStream.Close();
                response.Close();
                return responseFromServer;
            }
            catch (WebException e)
            {
                return ("Error:" + e.Status);
            }
            catch (Exception e)
            {
                return ("Error:" + e.Message);
            }
        }
        
        #endregion
        
        #region Get Refunds
        private void KeepGetRefunds()
        {
            try
            {
                GetRefunds();
            }
            catch (Exception exp)
            {
                Console.WriteLine("获得所有交易退款数据出错：{0},程序将重新启动", exp.Message);
                //this.KeepGetRefunds();
            }
        }
        public void GetRefunds()
        {
            Console.WriteLine("开始获得所有交易数据 at" + DateTime.Now);
            Taobao.Model.Shop[] ss = ActiveRecordBase<Taobao.Model.Shop>.FindAll();
            foreach (Taobao.Model.Shop s in ss)
            {
                int tp;
                int i;
                int pagesize = 50;
                Console.WriteLine(string.Concat(new object[] { "网店名称：", s.Name, "at", DateTime.Now }));
                TopXmlRestClient topClient = CreateClient(s);
                RefundsReceiveGetRequest rgr = new RefundsReceiveGetRequest();
                rgr.Fields = "refund_id, tid,title,total_fee,refund_fee, status, created, modified,num_iid";
                rgr.StartModified = DateTime.Now.AddDays(-UpdateBeforeDays);
                rgr.PageSize = new int?(pagesize);
                PageList<Top.Api.Domain.Refund> rs = topClient.RefundsReceiveGet(rgr);
                Console.WriteLine("退款单数量：{0}", rs.TotalResults);
                foreach (Taobao.Top.Api.Domain.Refund r in rs.Content)
                {
                    SaveRefund(s, r);
                }
                if (rs.TotalResults > pagesize)
                {
                    tp = (int)((rs.TotalResults / pagesize) + ((rs.TotalResults % pagesize == 0) ? 1 : 2));

                    i = 2;
                    while (i < tp)
                    {
                        Console.WriteLine("得到第" + i + "页订单");
                        rgr.PageNo = new int?(i);
                        PageList<Taobao.Top.Api.Domain.Refund> rssn = topClient.RefundsReceiveGet(rgr);
                        foreach (Taobao.Top.Api.Domain.Refund rfn in rssn.Content)
                        {
                            SaveRefund(s, rfn);
                        }
                        i++;
                    }
                }                 
            }
        }

        private void SaveRefund(Taobao.Model.Shop s, Taobao.Top.Api.Domain.Refund r)
        {
            try
            {
                Taobao.Model.Refund rf;
                CountQuery cq = new CountQuery(typeof(Taobao.Model.Refund), "RefundID=?", new object[] { r.RefundId });
                if (((int)ActiveRecordBase.ExecuteQuery(cq)) == 0)
                {
                    rf = new Taobao.Model.Refund();
                    rf.Created = DateTime.Parse(r.Created);
                    rf.Modified = DateTime.Parse(r.Modified);
                    rf.Status = r.Status;
                    rf.TaobaoID = r.Tid;
                    rf.RefundID = r.RefundId;
                    rf.Title = r.Title;
                    if (r.NumIid > 0)
                    {
                        rf.ItemNumID = r.NumIid;
                    }
                    if (r.RefundFee != null)
                    {
                        rf.Refundfee = decimal.Parse(r.RefundFee);
                    }
                    if (r.TotalFee != null)
                    {
                        rf.Totalfee = decimal.Parse(r.TotalFee);
                    }
                    rf.Shop = s;
                    rf.Create();
                    Console.WriteLine(string.Concat(new object[] { "获得退款单号：", r.RefundId, "at", DateTime.Now }));
                }
                else
                {
                    rf = ActiveRecordBase<Taobao.Model.Refund>.FindOne(new ICriterion[] { Restrictions.Eq("RefundID", r.RefundId) });
                    if (r.Modified != null)
                    {
                        rf.Modified = DateTime.Parse(r.Modified);
                    }
                    rf.Status = r.Status;
                    if (r.RefundFee != null)
                    {
                        rf.Refundfee = decimal.Parse(r.RefundFee);
                    }
                    if (r.TotalFee != null)
                    {
                        rf.Totalfee = decimal.Parse(r.TotalFee);
                    }
                    rf.Save();
                    Console.WriteLine(string.Concat(new object[] { "更新退款单号：", r.RefundId, "at", DateTime.Now }));
                }

                if (string.IsNullOrEmpty(rf.OuterID))
                {
                    SaveRefundOtherInfo(r);
                }
            }
            catch
            {
                Console.WriteLine(string.Concat(new object[] { "更新退款单号：", r.RefundId, "at", DateTime.Now," 失败 " }));
            }
        }

        
        private void SaveRefundOtherInfo(Taobao.Top.Api.Domain.Refund r) 
        {
            try
            {
                Taobao.Model.Refund rf;
                CountQuery cq = new CountQuery(typeof(Taobao.Model.Refund), "RefundID=?", new object[] { r.RefundId });
                if (((int)ActiveRecordBase.ExecuteQuery(cq)) > 0)
                {
                    rf = ActiveRecordBase<Taobao.Model.Refund>.FindOne(new ICriterion[] { Restrictions.Eq("RefundID", r.RefundId) });

                    TopXmlRestClient topClient = CreateClient(rf.Shop);
                    try
                    {
                        TradeFullinfoGetRequest req = new TradeFullinfoGetRequest();
                        req.Fields = "num_iid,sid,tid,status";
                        req.Tid = new long?(rf.TaobaoID);
                        Top.Api.Domain.Trade rsp = topClient.TradeFullinfoGet(req);
                        if (rsp != null && (rsp.NumIid>0||r.NumIid>0)) 
                        {
                            rf.ItemNumID = rsp.NumIid > 0 ? rsp.NumIid : r.NumIid;

                            try
                            {
                                ItemGetRequest itemGetReq = new ItemGetRequest();
                                itemGetReq.NumIid = new long?(rf.ItemNumID);
                                itemGetReq.Fields = "num_iid,outer_id";
                                Top.Api.Domain.Item item = topClient.ItemGet(itemGetReq);
                                if (item != null)
                                {
                                    rf.OuterID = item.OuterId;

                                    rf.Save();
                                    Console.WriteLine(string.Concat(new object[] { "更新退款单号：", r.RefundId, " 的ItemNumID 和 OuterID信息", "at", DateTime.Now }));
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(string.Concat(new object[] { "更新退款单号：", r.RefundId, " 的ItemNumID 和 OuterID信息失败,", ex.Message, " at", DateTime.Now }));
                            }
                           
                        }
                    }
                    catch
                    {
                    }
                     
                }
            }
            catch 
            { 
            }
        }
        #endregion

        #region Get Trades
        
        private void KeepGetTrades()
        {
            try
            {
                GetTrades();
            }
            catch (Exception exp)
            {
                Console.WriteLine("获得所有交易数据出错：{0},程序将重新启动", exp.Message);
                //this.KeepGetTrades();
            }
        }

        public void GetTrades()
        {
            Console.WriteLine("开始获得所有交易数据 at" + DateTime.Now);
            Taobao.Model.Shop[] ss = ActiveRecordBase<Taobao.Model.Shop>.FindAll();
            foreach (Taobao.Model.Shop s in ss)
            {
                int tp;
                int i;
                int pagesize = 50;
                Console.WriteLine(string.Concat(new object[] { "网店名称：", s.Name, "at", DateTime.Now }));
                TopXmlRestClient topClient = CreateClient(s);                 

                foreach (string[] statusInfo in GetUpdateTradeStatus())
                {
                    GetTradesOfShop(s, topClient, pagesize, statusInfo[0], statusInfo[1]);           
                }
                //GetTradesOfShop(s, topClient, pagesize, "WAIT_BUYER_PAY", "等待买家付款的订单");   //ALL_WAIT_PAY :WAIT_BUYER_PAY,TRADE_NO_CREATE_PAY  
                //GetTradesOfShop(s, topClient, pagesize, "WAIT_SELLER_SEND_GOODS", "等待卖家发货的订单");           
            }
        }
         #region Modified By Yuliang Ding

        private void GetTradesOfShop(Model.Shop s, TopXmlRestClient topClient,int pagesize,string tradeStatus,string title)
        {
            try
            {
                int i = 0, tp = 0;
                TradesSoldGetRequest req = new TradesSoldGetRequest();
                req.PageSize = new int?(pagesize);
                req.StartCreated = DateTime.Now.AddDays(-UpdateBeforeDays);//new DateTime?(DateTime.Parse("1990.01.01"));
                req.EndCreated = new DateTime?(DateTime.Now);
                req.Fields = " title, type, created, sid, tid,end_time, received_payment, alipay_no, iid, num, price, shipping_type,buyer_memo, seller_memo,";
                req.Status = tradeStatus;// "WAIT_SELLER_SEND_GOODS";
                PageList<Taobao.Top.Api.Domain.Trade> rsp = topClient.TradesSoldGet(req);
                Console.WriteLine(string.Concat(new object[] { title + "数:", rsp.TotalResults, "从", req.StartCreated, "到", req.EndCreated }));
                if ((rsp.Content == null) || (rsp.Content.Count < 1))
                {
                    Console.WriteLine("没有新增" + title);
                }
                else
                {
                    List<Taobao.Top.Api.Domain.Trade> trades = rsp.Content;
                    foreach (Taobao.Top.Api.Domain.Trade t in trades)
                    {
                        SaveTrade(s, t);
                    }
                    if (rsp.TotalResults > pagesize)
                    {
                        tp = (int)((rsp.TotalResults / pagesize) + ((rsp.TotalResults % pagesize == 0) ? 1 : 2));
                        for (i = 2; i < tp; i++)
                        {
                            try
                            {
                                Console.WriteLine("得到第" + i + "页" + title);
                                req.PageNo = new int?(i);
                                List<Taobao.Top.Api.Domain.Trade> tradesn = topClient.TradesSoldGet(req).Content;
                                foreach (Taobao.Top.Api.Domain.Trade t in tradesn)
                                {
                                    SaveTrade(s, t);
                                }
                            }
                            catch
                            {
                                Console.WriteLine("得到第" + i + "页" + title + "失败");
                            }
                        }
                    }
                }
            }
            catch { }
        }

        #endregion

         private  void SaveTrade(Taobao.Model.Shop s, Taobao.Top.Api.Domain.Trade t)
        {
            try
            {
                CountQuery cq = new CountQuery(typeof(Taobao.Model.Trade), "TaobaoTid=?", new object[] { t.Tid });
                if (((int)ActiveRecordBase.ExecuteQuery(cq)) == 0)
                {
                    Taobao.Model.Trade art = new Taobao.Model.Trade();
                    art.AlipayNo = t.AlipayNo;
                    art.Buyer_nick = t.BuyerNick;
                    art.BuyerMemo = "买家备注：" + t.BuyerMemo + "||买家留言：" + t.BuyerMessage;
                    art.SellerMemo = t.SellerMemo;
                    art.OrderNum = (short)t.Num;
                    art.OrderPrice = t.Payment;
                    art.Shop = s;
                    art.Status = t.Status;
                    art.Seller_nick = t.SellerNick;
                    art.TaobaoTid = t.Tid;
                    art.Created = new DateTime?(DateTime.Parse(t.Created));
                    Console.WriteLine("订单创建日期" + art.Created);
                    if (t.PayTime != null)
                    {
                        art.PayTime = new DateTime?(DateTime.Parse(t.PayTime));
                    }
                    else
                    {
                        art.PayTime = new DateTime?(DateTime.Parse("1990.01.01"));
                    }
                    if (t.EndTime != null)
                    {
                        art.EndTime = new DateTime?(DateTime.Parse(t.EndTime));
                    }
                    else
                    {
                        art.EndTime = new DateTime?(DateTime.Parse("1990.01.01"));
                    }

                    // 新建一个 Trade的时候，不需要 判断 Process.
                    // 我们目前只有下载 WAIT_SELLER_SEND_GOODS，WAIT_BUYER_PAY，TRADE_NO_CREATE_PAY
                    // 这三种状态下的订单
                    if (t.Status == "WAIT_SELLER_SEND_GOODS")
                    {
                        art.TProcess = 0;
                    }
                    else if (t.Status == "WAIT_BUYER_PAY")
                    {
                        art.TProcess = -1;
                    }
                    else if (t.Status == "TRADE_NO_CREATE_PAY")
                    {
                        art.TProcess = -2;
                    }
                    art.Create();

                    Console.WriteLine("保存订单成功，订单ID：{0} at{1}", t.Tid, DateTime.Now);
                }
                else
                {
                    Console.WriteLine("订单已经存在 订单:" + t.Tid);
                }
            }
            catch
            {
                Console.WriteLine("保存订单失败，订单ID：{0} at{1}", t.Tid, DateTime.Now);
            }
        }
        #endregion
       
        #region Get Trade Info
        private void KeepGetTradeInfo()
        {
            try
            {
                GetTradesInfo();
            }
            catch (Exception exp)
            {
                Console.WriteLine("得到交易详细信息出错：{0},程序将重新启动", exp.Message);
                //this.KeepGetTradeInfo();
            }
        }

        public void GetTradesInfo()
        {
            try
            {
                Console.WriteLine("开始获得所有交易数据 at" + DateTime.Now);
                Taobao.Model.Shop[] ss = ActiveRecordBase<Taobao.Model.Shop>.FindAll();
                foreach (Taobao.Model.Shop s in ss)
                {
                    int tp;
                    int i;
                    int pagesize = 50;
                    Console.WriteLine(string.Concat(new object[] { "网店名称：", s.Name, "at", DateTime.Now }));
                    TopXmlRestClient topClient = CreateClient(s);

                    foreach (string[] statusInfo in GetUpdateTradeStatus())
                    {
                        try
                        {
                            GetTradeInfosOfShop(s, topClient, pagesize, statusInfo[0], statusInfo[1]);
                        }
                        catch { }
                    }
                }
            }
            catch { }
        }

        private  void SaveTradeInfo(Taobao.Model.Trade art, Taobao.Top.Api.Domain.Trade trade)
        {
            TransactionScope t2 = new TransactionScope(TransactionMode.New);
            try
            {
                art.ReceiverAddress = trade.ReceiverAddress;
                art.ReceiverCity = trade.ReceiverCity;
                art.ReceiverDistrict = trade.ReceiverDistrict;
                art.ReceiverMobile = trade.ReceiverMobile;
                art.ReceiverName = trade.ReceiverName;
                art.ReceiverPhone = trade.ReceiverPhone;
                art.ReceiverState = trade.ReceiverState;
                art.ReceiverZip = trade.ReceiverZip;
                art.SellerName = trade.SellerName;
                art.SellerMobile = trade.SellerMobile;
                art.BuyerAlipayNo = trade.BuyerAlipayNo;
                art.PostFee = trade.PostFee;
                art.ShippingType = trade.ShippingType;
                art.Type = trade.Type;
                art.Discount_Fee = new decimal?(trade.Orders.Sum<Taobao.Top.Api.Domain.Order>(delegate(Taobao.Top.Api.Domain.Order o)
                {
                    if (o.DiscountFee != null)
                    {
                        return decimal.Parse(o.DiscountFee);
                    }
                    return 0M;
                }));
                art.Adjust_Fee = new decimal?(trade.Orders.Sum<Taobao.Top.Api.Domain.Order>(delegate(Taobao.Top.Api.Domain.Order o)
                {
                    if (o.AdjustFee != null)
                    {
                        return decimal.Parse(o.AdjustFee);
                    }
                    return 0M;
                }));
                art.Payment = trade.Payment;
                if (trade.PayTime != null)
                {
                    art.PayTime = new DateTime?(DateTime.Parse(trade.PayTime));
                }
                if (trade.EndTime != null)
                {
                    art.EndTime = new DateTime?(DateTime.Parse(trade.EndTime));
                }
                if (art.TProcess <= 0)
                {
                    if (trade.Status == "WAIT_SELLER_SEND_GOODS")
                    {
                        if (art.TProcess < 0)
                        {
                            art.TProcess = 0;
                        }
                    }
                    else if (trade.Status == "WAIT_BUYER_PAY")
                    {
                        art.TProcess = -1;
                    }
                    else if (trade.Status == "TRADE_NO_CREATE_PAY")
                    {
                        art.TProcess = -2;
                    }
                }
                art.Status = trade.Status;
                art.Seller_nick = trade.SellerNick;
                art.Buyer_nick = trade.BuyerNick;
                art.BuyerMemo = "买家备注：" + trade.BuyerMemo + "||买家留言：" + trade.BuyerMessage;
                art.SellerMemo = trade.SellerMemo;
                int sellerFlag = trade.SellerFlag;
                art.SellerFlag = trade.SellerFlag.ToString();
                art.AlipayNo = trade.AlipayNo;
                art.OrdersTitle = trade.Orders[0].Title;
                art.OrderNum = (short)trade.Orders.Count;
                if (art.OrderInfoes.Count == 0)
                {
                    foreach (Taobao.Top.Api.Domain.Order o in trade.Orders)
                    {
                        OrderInfo oi = new OrderInfo();
                        oi.NumIid = o.NumIid;
                        oi.Title = o.Title;
                        oi.Trade = art;
                        oi.Number = o.Num;
                        oi.Price = o.Price;
                        oi.Iid = o.Iid;
                        oi.ItemMealName = o.ItemMealName;
                        if (o.AdjustFee != null)
                        {
                            oi.Adjust_Fee = new decimal?(decimal.Parse(o.AdjustFee));
                        }
                        if (o.DiscountFee != null)
                        {
                            oi.Discount_Fee = new decimal?(decimal.Parse(o.DiscountFee));
                        }
                        if (o.Payment != null)
                        {
                            oi.Payment = new decimal?(decimal.Parse(o.Payment));
                        }
                        long refundId = o.RefundId;
                        oi.RefundId = new long?(o.RefundId);
                        if (o.Status != null)
                        {
                            oi.Status = o.Status;
                        }
                        if (o.Modified != null)
                        {
                            oi.Modified = new DateTime?(DateTime.Parse(o.Modified));
                        }
                        //oi.Save();
                        //Item item = GetItemInfo(oi);
                        //oi.SkuPropertiesName = o.SkuPropertiesName;
                        //oi.OuterIId = item.OuterId;
                        //oi.NumIid = item.NumIid;
                        //oi.SkuID = o.SkuId;
                        oi.SkuPropertiesName = o.SkuPropertiesName;
                        oi.OuterIId = string.IsNullOrEmpty(o.OuterSkuId) ? o.OuterIid : o.OuterSkuId;
                        oi.NumIid = o.NumIid;
                        oi.SkuID = o.SkuId;
                        oi.Save();
                    }
                }
                art.Save();
                if (trade.Status != "TRADE_NO_CREATE_PAY" && trade.Status != "WAIT_BUYER_PAY")
                {
                    OutSent os = art.OutSent ?? new OutSent();
                    if (art.Status == "WAIT_SELLER_SEND_GOODS")
                    {
                        os.Message = "待发货";
                    }
                    else
                    {
                        os.Message = "发货成功";
                        Console.WriteLine("更新一个已发货信息,订单ID：{0}", art.TaobaoTid);
                    }
                    os.Trade = art;
                    os.Save();
                }
                Console.WriteLine("获得详细信息订单ID：{0}  at{1}", art.TaobaoTid, DateTime.Now);
                t2.VoteCommit();
            }
            catch (Exception)
            {
                t2.VoteRollBack();
            }
            finally
            {
                if (t2 != null)
                {
                    t2.Dispose();
                }
            }
        }

        private void SaveTradeInfo(Taobao.Model.Shop shop, Taobao.Top.Api.Domain.Trade trade)
        {
            try
            {
                Taobao.Model.Trade[] mTrades = ActiveRecordBase<Taobao.Model.Trade>.FindAllByProperty("TaobaoTid", trade.Tid);
                if (mTrades != null && mTrades.Length > 0)
                {
                    var mTrade = mTrades.FirstOrDefault(t => t.Shop != null && t.Shop.ShopId == shop.ShopId);
                    if (mTrade != null)
                    {
                        SaveTradeInfo(mTrade, trade);
                    }
                }
            }
            catch { }
        }

        private void GetTradeInfosOfShop(Model.Shop s, TopXmlRestClient topClient, int pagesize, string tradeStatus, string title)
        {
            try
            {
                int i = 0, tp = 0;
                TradesSoldGetRequest req = new TradesSoldGetRequest();
                req.PageSize = new int?(pagesize);
                req.StartCreated = DateTime.Now.AddDays(-UpdateBeforeDays);// new DateTime?(DateTime.Parse("1990.01.01"));
                req.EndCreated = new DateTime?(DateTime.Now);
                req.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders";//.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";                  
                req.Status = tradeStatus;// "WAIT_SELLER_SEND_GOODS";
                PageList<Taobao.Top.Api.Domain.Trade> rsp = topClient.TradesSoldGet(req);
                Console.WriteLine(string.Concat(new object[] { title + "数:", rsp.TotalResults, "从", req.StartCreated, "到", req.EndCreated }));
                if ((rsp.Content == null) || (rsp.Content.Count < 1))
                {
                    Console.WriteLine("没有要更新的" + title);
                }
                else
                {
                    List<Taobao.Top.Api.Domain.Trade> trades = rsp.Content;
                    foreach (Taobao.Top.Api.Domain.Trade t in trades)
                    {
                        try
                        {
                            TradeFullinfoGetRequest fullInfoReq = new TradeFullinfoGetRequest();
                            //req.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";
                            fullInfoReq.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders";//.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";                                
                            fullInfoReq.Tid = new long?(t.Tid);
                            Top.Api.Domain.Trade fullInforsp = topClient.TradeFullinfoGet(fullInfoReq);
                            SaveTradeInfo(s, fullInforsp);
                        }
                        catch
                        {
                        }

                        //SaveTradeInfo(s, t);
                    }
                    if (rsp.TotalResults > pagesize)
                    {
                        tp = (int)((rsp.TotalResults / pagesize) + ((rsp.TotalResults % pagesize == 0) ? 1 : 2));

                        for (i = 2; i < tp; i++)
                        {
                            Console.WriteLine("得到第" + i + "页" + title);
                            req.PageNo = new int?(i);
                            List<Taobao.Top.Api.Domain.Trade> tradesn = topClient.TradesSoldGet(req).Content;
                            foreach (Taobao.Top.Api.Domain.Trade t in tradesn)
                            {
                                try
                                {
                                    TradeFullinfoGetRequest fullInfoReq = new TradeFullinfoGetRequest();
                                    //req.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";
                                    fullInfoReq.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders";//.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";                                
                                    fullInfoReq.Tid = new long?(t.Tid);
                                    Top.Api.Domain.Trade fullInforsp = topClient.TradeFullinfoGet(fullInfoReq);
                                    SaveTradeInfo(s, fullInforsp);

                                }
                                catch
                                {
                                }
                                //SaveTradeInfo(s, t);
                            }
                        }
                    }
                }
            }
            catch { }
        }
        #endregion

        #region Update Trade Info

         private void KeepUpdataTradesInfo()
        {
            try
            {
                GetTradesEndTime();

                UpdataTradesInfo();
            }
            catch (Exception exp)
            {
                Console.WriteLine("跟新交易详细信息出错：{0},程序将重新启动", exp.Message);
                //this.KeepUpdataTradesInfo();
            }
        }

        private  void GetTradesEndTime()
        {
            try
            {
                TopXmlRestClient topClient;
                TradeFullinfoGetRequest req;
                Taobao.Top.Api.Domain.Trade rsp;
                Exception exp;
                Taobao.Model.Trade[] ts = ActiveRecordBase<Taobao.Model.Trade>.FindAll(new ICriterion[] { Restrictions.Or(Restrictions.Eq("EndTime", 
                DateTime.Parse("1990.01.01")),//DateTime.Now.AddMonths(-6)), //
                Restrictions.IsNull("EndTime")) });
                Console.WriteLine("需要获得EndTime订单数：{0} at{1}", ts.Length, DateTime.Now);
                foreach (Taobao.Model.Trade trade in ts)
                {
                    try
                    {
                        topClient = CreateClient(trade.Shop);
                        req = new TradeFullinfoGetRequest();
                        //req.Fields = "num_iid,seller_nick,end_time, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo,orders.num_iid ";
                        req.Fields = "num_iid,seller_nick,end_time, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders,seller_flag";//,orders.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo,orders.num_iid ";
                        req.Tid = new long?(trade.TaobaoTid);
                        rsp = topClient.TradeFullinfoGet(req);
                        SaveTradeInfo(trade, rsp);
                    }
                    catch (Exception exception2)
                    {
                        exp = exception2;
                        Console.WriteLine("获得EndTime 订单ID：{0} 出错{1} at{2}", trade.TaobaoTid, exp.Message, DateTime.Now);
                    }
                }
            }
            catch { }
        }

        public void UpdataTradesInfo()
        {
            try
            {
                //Modified By Yuliang Ding
                List<Model.Trade> traderList = new List<Model.Trade>();
                foreach (string[] statusInfo in GetUpdateTradeStatus())
                {
                    Taobao.Model.Trade[] ts = ActiveRecordBase<Taobao.Model.Trade>.FindAllByProperty("Status", statusInfo[0]);
                    if (ts != null && ts.Length > 0)
                    {
                        traderList.AddRange(ts);
                    }
                }

                Console.WriteLine("需要跟新的订单数：" + traderList.Count.ToString());
                foreach (Taobao.Model.Trade t in traderList)
                {
                    try
                    {
                        TopXmlRestClient topClient = CreateClient(t.Shop);
                        TradeFullinfoGetRequest req = new TradeFullinfoGetRequest();
                        //req.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";
                        req.Fields = "num_iid,seller_nick, buyer_nick, title, type, created, sid, tid,  status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, buyer_memo, seller_memo, alipay_no, buyer_message,  iid, num, price, buyer_alipay_no, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone, buyer_email, shipping_type, trade_memo, is_3D ,orders";//.title, orders.price,orders.oid, orders.num, orders.iid,  orders.status, orders.tid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.timeout_action_time,orders.sku_properties_name, orders.item_meal_name, item_memo ";                                
                        req.Tid = new long?(t.TaobaoTid);
                        Top.Api.Domain.Trade rsp = topClient.TradeFullinfoGet(req);
                        SaveTradeInfo(t, rsp);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("需要跟新的订单ID：{0} 出错{1} at{2}", t.TaobaoTid, ex.Message, DateTime.Now);
                    }
                }
            }
            catch { }
        }
        #endregion       
        
        #region Sent

        private void KeepSent()
        {
            try
            {
                SendOutSid();
            }
            catch (Exception exp)
            {
                Console.WriteLine("提交物流信息出错：{0},程序将重新启动", exp.Message);
                //this.KeepSent();
            }
        }
         private void KeepSentBeforeAllAction()
        {
            try
            {
                SendOutSid();
            }
            catch (Exception exp)
            {
                Console.WriteLine("提交物流信息出错：{0}", exp.Message); 
            }
        }
        public void SendOutSid()
        {
            Exception e;
            Console.WriteLine("待发货订单数：" + ActiveRecordBase<OutSent>.FindAllByProperty("Message", "待发货").Length);
            Console.WriteLine("待同步订单数：" + ActiveRecordBase<OutSent>.FindAll(new ICriterion[] { Restrictions.Eq("Message", "待发货"), Restrictions.IsNotNull("OutSid") }).Length);
            foreach (OutSent os in ActiveRecordBase<OutSent>.FindAll(new ICriterion[] { Restrictions.Eq("Message", "待发货"), Restrictions.IsNotNull("OutSid"), Restrictions.IsNotNull("CompanyCode"), Restrictions.IsNull("Failure") }))
            {
                try
                {
                    sellerSentTrade(os.Trade);
                }
                catch (Exception exception1)
                {
                    e = exception1;
                    Console.WriteLine("发送时出错,错误为:" + e.Message);
                    Thread.Sleep(0xbb8);
                    sellerSentTrade(os.Trade);
                }
                Console.WriteLine("发送一次");
            }
            OutSent[] virtual_goods = ActiveRecordBase<OutSent>.FindAll(new ICriterion[] { Restrictions.Eq("Message", "待发货"), Restrictions.Eq("OrderType", "virtual_goods") });
            Console.WriteLine("待发虚拟物品数量为：" + virtual_goods.Length);
            foreach (OutSent os in virtual_goods)
            {
                try
                {
                    sellerSentTrade(os.Trade);
                }
                catch (Exception exception2)
                {
                    e = exception2;
                    Console.WriteLine("发送时出错,错误为:" + e.Message);
                    Thread.Sleep(0xbb8);
                    sellerSentTrade(os.Trade);
                }
                Console.WriteLine("发送一次");
            }
        }

        
        public void sellerSentTrade(Taobao.Model.Trade trade)
        {
            try
            {
                TopXmlRestClient client = new TopXmlRestClient("http://gw.api.taobao.com/router/rest", trade.Shop.AppKey, trade.Shop.AppSecret);
                DeliverySendRequest req = new DeliverySendRequest();
                req.Tid = new long?(trade.TaobaoTid);
                if (trade.OutSent.OrderType != "virtual_goods")
                {
                    if (trade.OutSent.CompanyCode == null)
                    {
                        req.CompanyCode = trade.Shop.Sender.CompanyCode;
                    }
                    else
                    {
                        req.CompanyCode = trade.OutSent.CompanyCode;
                    }
                    req.Memo = trade.OutSent.Memo;
                    req.OutSid = trade.OutSent.OutSid;
                    req.SellerAddress = trade.Shop.Sender.Address;
                    req.SellerAreaId = trade.Shop.Sender.AreaID;
                    req.SellerMobile = trade.Shop.Sender.Mobile;
                    req.SellerName = trade.Shop.Sender.Name;
                    req.SellerZip = trade.Shop.Sender.Zip;
                    req.SellerPhone = trade.Shop.Sender.Phone;
                }
                else
                {
                    req.OrderType = trade.OutSent.OrderType;
                }
                try
                {
                    if (client.DeliverySend(req).IsSuccess)
                    {
                        trade.OutSent.Message = "发货成功";
                        trade.Status = "WAIT_BUYER_CONFIRM_GOODS";
                        Console.WriteLine("发货成功");
                    }
                    else
                    {
                        trade.OutSent.Message = "发货失败";
                        trade.OutSent.Failure = "1";
                    }
                }
                catch (Exception exp)
                {
                    trade.OutSent.Failure = exp.ToString();
                }
                trade.OutSent.Update();
                trade.Save();
            }
            catch { }
        }
        #endregion      

        #region Prepare Operations
        
        
        [Serializable]
        [XmlRoot("xmldoc")]
        public class PrepareResult
        {
            [XmlElementAttribute("status")]
            public string Status
            { get; set; }
        }

        private PrepareResult GetPrepareResult(Stream resultStream)
        {
            PrepareResult result =new PrepareResult ();
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(PrepareResult));
                XmlReader xReader = XmlReader.Create(resultStream);
                if (serializer.CanDeserialize(xReader))
                {
                    result = serializer.Deserialize(xReader) as PrepareResult;
                }
            }
            catch { }
            return result;
        }

        private bool PreparingOperation()
        {
            IDictionary<string, string> paramDict = new Dictionary<string, string>();
            paramDict.Add(ConfigurationManager.AppSettings.Keys[0], ConfigurationManager.AppSettings[0]);
            HttpWebResponse response = WebUtils.DoPostResponse(ConfigurationManager.AppSettings["url"], paramDict);
            PrepareResult result = GetPrepareResult(response.GetResponseStream());
            return (result.Status == "Done");
        }

        private void KeepPreparingOperation()
        {
            bool result = false;
            try
            {
                result = PreparingOperation();
            }
            catch (Exception e)
            {                
            }
            finally
            {
                if (!result)
                {
                    Console.WriteLine("处理其他的准备工作没有成功,程序将重新启动");
                    this.KeepPreparingOperation();
                }
                else
                {
                    Console.WriteLine("处理其他的准备工作已完成");
                }
            }
        }
        #endregion

        #region Others


        private void 获得待发货订单数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void 删除数据结构ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                ActiveRecordStarter.DropSchema();
                MessageBox.Show("删除数据结构成功");
            }
            catch
            {
                MessageBox.Show("删除数据结构失败");
            }
        }

        private void 程序配置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigurationForm form = new ConfigurationForm();
            form.ShowDialog();
        }

        #endregion
         

    }

    #region Tool Configuration

    public class ToolConfiguration
    {
        public bool PreparingOperation { get; set; }
        public bool SentBeforeAllAction { get; set; }
        public bool GetRefunds { get; set; }
        public bool GetTrades { get; set; }
        public bool GetTradesInfo { get; set; }
        public bool UpdateTradesInfo { get; set; }
        public bool Sent { get; set; }
        public bool WaitBuyerPay { get; set; }
        public bool TradeNoCreatePay { get; set; }
        public bool WaitSellerSendGoods { get;set;}

        protected ToolConfiguration() 
        {
            this.GetRefunds = true;
            this.GetTrades = true;
            this.GetTradesInfo = true;
            this.PreparingOperation = true;
            this.Sent = true;
            this.SentBeforeAllAction = true;
            this.UpdateTradesInfo = true;
            this.WaitBuyerPay = true;
            this.WaitSellerSendGoods = true;
            this.TradeNoCreatePay = true;
        }

        public static ToolConfiguration Load()
        {
            var xDocument = XDocument.Load("configuration.xml");
            var processElement = xDocument.Root.Element("process");
            var configuration = new ToolConfiguration();
            configuration.PreparingOperation = GetProcessEnableAttribute(processElement,"preparingOperation");
            configuration.SentBeforeAllAction = GetProcessEnableAttribute(processElement, "sentBeforeAllAction");
            configuration.GetRefunds = GetProcessEnableAttribute(processElement, "getRefunds");
            configuration.GetTrades = GetProcessEnableAttribute(processElement, "getTrades");
            configuration.GetTradesInfo = GetProcessEnableAttribute(processElement, "getTradesInfo");
            configuration.UpdateTradesInfo = GetProcessEnableAttribute(processElement, "updateTradesInfo");
            configuration.Sent = GetProcessEnableAttribute(processElement, "sent");
            configuration.TradeNoCreatePay = GetProcessEnableAttribute(processElement, "tradeNoCreatePay");
            configuration.WaitBuyerPay = GetProcessEnableAttribute(processElement, "waitBuyerPay");
            configuration.WaitSellerSendGoods = GetProcessEnableAttribute(processElement, "waitSellerSendGoods");
            return configuration;
        }

        private static bool GetProcessEnableAttribute(XElement processElement, XName childElementName)
        { 
            var childElement = processElement.Element(childElementName);
            return childElementName != null && childElement.Attribute("enable") != null && childElement.Attribute("enable").Value == "true";
        }
        private static void SetProcessEnableAttribtue(XElement processElement, XName childElementName, bool enabled)
        {
            var childElement = processElement.Element(childElementName);
            if (childElement == null)
            {
                childElement = new XElement(childElementName);
                processElement.Add(childElement);
            }
            var enableAttribute = childElement.Attribute("enable");
            if (enableAttribute == null)
            {
                enableAttribute = new XAttribute("enable","true");
                childElement.Add(enableAttribute);
            }
            enableAttribute.Value = enabled ? "true" : "false";
        }

        public static void Save(ToolConfiguration configuration)
        {
            var xDocument = XDocument.Load("configuration.xml");
            var processElement = xDocument.Root.Element("process");
            SetProcessEnableAttribtue(processElement, "preparingOperation", configuration.PreparingOperation);
            SetProcessEnableAttribtue(processElement, "sentBeforeAllAction", configuration.SentBeforeAllAction);
            SetProcessEnableAttribtue(processElement, "getRefunds", configuration.GetRefunds);
            SetProcessEnableAttribtue(processElement, "getTrades", configuration.GetTrades);
            SetProcessEnableAttribtue(processElement, "getTradesInfo", configuration.GetTradesInfo);
            SetProcessEnableAttribtue(processElement, "updateTradesInfo", configuration.UpdateTradesInfo);
            SetProcessEnableAttribtue(processElement, "sent", configuration.Sent);
            SetProcessEnableAttribtue(processElement, "tradeNoCreatePay", configuration.TradeNoCreatePay);
            SetProcessEnableAttribtue(processElement, "waitBuyerPay", configuration.WaitBuyerPay);
            SetProcessEnableAttribtue(processElement, "waitSellerSendGoods", configuration.WaitSellerSendGoods);
            xDocument.Save("configuration.xml");
        }

    }
    #endregion
 
}

